package com.laicunba.service.task;

import java.util.Date;
import java.util.Map;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;

import com.laicunba.event.WithdrawToBankCardEvent;
import com.laicunba.pojo.FinancingTargetBidDO;
import com.laicunba.pojo.FuiouPayForReqDO;
import com.laicunba.pojo.TaskDO;
import com.laicunba.pojo.WithdrawDO;
import com.laicunba.service.FinancingTargetBidService;
import com.laicunba.service.WithdrawService;
import com.laicunba.service.exception.MyException;
import com.laicunba.service.fuiou.FuiouPayForReqService;
import com.laicunba.service.fuiou.FuiouStatusQueryService;
import com.laicunba.service.fuiou.FuiouStatusQueryService.Result;
import com.laicunba.util.AssertUtil;
import com.laicunba.util.StringUtil;

@Service
public class FuiouWithdrawTaskExecutor extends TaskExecutorTemplate implements TaskExecutor, ApplicationEventPublisherAware {
	private ApplicationEventPublisher applicationEventPublisher;
	@Autowired
	private FuiouPayForReqService fuiouPayForReqService;
	@Autowired
	private WithdrawService withdrawService;
	@Autowired
	private FinancingTargetBidService financingTargetBidService;

	@Override
	public String getType() {
		return "FUIOU_WITHDRAW";
	}

	@SuppressWarnings("rawtypes")
	@Override
	public boolean execute(TaskDO taskDO, Object context) {
		if (context == null || !(context instanceof Map)) {
			return false;
		}
		Map map = (Map) context;
		try {
			if ("success".equalsIgnoreCase(taskDO.getStatus())) {
				return true;
			}
			// 验证数据的有效性
			JSONObject param = (JSONObject) new JSONParser().parse(taskDO.getParam());
			String withdrawId = (String) param.get("wid");
			AssertUtil.assertNotNull(withdrawId, "WID_NOT_EXIST");
			String fprid = (String) param.get("fprid");
			AssertUtil.assertNotNull(fprid, "FPRID_NOT_EXIST");
			FuiouPayForReqDO fuiouPayForReqDO = fuiouPayForReqService.get(FuiouPayForReqDO.class, fprid);
			AssertUtil.assertNotNull(fuiouPayForReqDO, "FUIOU_PAY_FOR_REQ_DO_NOT_EXIST");
			WithdrawDO withdrawDO = withdrawService.get(WithdrawDO.class, withdrawId);
			AssertUtil.assertNotNull(withdrawDO, "WITHDRAW_DO_NOT_EXIST");
			AssertUtil.assertTrue("send".equalsIgnoreCase(withdrawDO.getStatus()), "WITHDRAW_DO_NOT_SEND_STATUS");
			String bid = (String) param.get("bid");
			FinancingTargetBidDO bidDO = null;
			if ("CPB".equalsIgnoreCase(withdrawDO.getType())) {
				AssertUtil.assertNotEmpty(bid, "BID_NOT_EXIST");
				bidDO = financingTargetBidService.get(FinancingTargetBidDO.class, bid);
				AssertUtil.assertNotNull(bidDO, "BID_DO_NOT_EXIST");
			}
			// 对比富友返回的状态
			FuiouStatusQueryService.Result statusResult = (Result) map.get(fuiouPayForReqDO.getOrderno());
			AssertUtil.assertNotNull(statusResult, "NOT_FOUND_STATUS_IN_FUIOU");
			AssertUtil.assertTrue("1".equals(statusResult.getState()), "STATUS_NOT_1 " + statusResult.toString());

			// 改已到账状态
			AssertUtil.assertTrue(withdrawService.finish(withdrawDO.getId(), withdrawDO.getCertificateId()), "WITHDRAW_DO_CHANGE2_TRANSFERD_FAIL");
			// 触发到账事件
			WithdrawToBankCardEvent event = null;
			if ("CPB".equalsIgnoreCase(withdrawDO.getType())) {
				if (StringUtil.isEmpty(bidDO.getBankName())) {
					bidDO.setBankName(withdrawDO.getBankName());
					bidDO.setBankCardNo(withdrawDO.getBankCardNo());
				}
				event = new WithdrawToBankCardEvent(bidDO);
			} else {
				event = new WithdrawToBankCardEvent(withdrawDO);
			}
			applicationEventPublisher.publishEvent(event);

			// 改变任务状态
			taskDO.setStatus("success");
			taskDO.setRunTime(new Date());
			taskDO.setResult(statusResult.toString());
			return taskService.updateSkipCheckOwner(taskDO);

		} catch (MyException e) {
			taskDO.setStatus("fail");
			taskDO.setRunTime(new Date());
			taskDO.setResult(e.getCode());
			taskService.updateSkipCheckOwner(taskDO);
		} catch (Exception e) {
			taskDO.setStatus("fail");
			taskDO.setRunTime(new Date());
			taskDO.setResult(e.getMessage());
			taskService.updateSkipCheckOwner(taskDO);
		}
		return false;
	}

	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
		this.applicationEventPublisher = applicationEventPublisher;
	}

}
